<template>
  <el-card shadow="always">
    <!---- -- -- -- 头部-- -- -- -- -- -- -->
    <div slot="header">
      <!-- 路径导航 -->
      <!-- <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item to="/"> <i class="el-icon-house"></i> 后台主页</el-breadcrumb-item>
        <el-breadcrumb-item to="/users">用户管理</el-breadcrumb-item>
      </el-breadcrumb> -->
      <Breadcrumb/>
    </div>
    <!---- -- -- -- 内容区域-- -- -- -- -- -- -->
    <!-- 筛选区域 -->
    <div class="filter-box">
      <div class="lt">
        <el-input placeholder="请输入内容"
                  clearable
                  @clear="getLoadList"
                  v-model="keywords"
                  size="small">
          <el-button slot="append"
                     icon="el-icon-search"
                     @click="getLoadList"></el-button>
        </el-input>
      </div>
      <div class="rt">
        <!-- 【增加功能】 1. 绑定增加按钮，打开弹框 -->
        <el-button type="primary"
                   @click="isAddShow=true"
                   size="small"
                   icon="el-icon-plus">增加</el-button>
      </div>
    </div>
    <!-- 表格区域 -->
    <div class="table-box">
      <!-- 表格 -->
      <!-- data属性表示表格的数据 -->
      <!--【列表功能】 4. 渲染数据 -->
      <el-table :data="list"
                border>
        <!-- 列信息 type表示列的类型，index表示序号列 selection选择列 -->
        <el-table-column align="center"
                         type="index"
                         label="#"></el-table-column>
        <el-table-column align="center"
                         label="用户名"
                         prop="username"></el-table-column>
        <el-table-column align="center"
                         label="邮箱"
                         prop="email"></el-table-column>
        <el-table-column align="center"
                         label="角色名"
                         prop="role_name"></el-table-column>
        <el-table-column align="center"
                         label="手机号"
                         prop="mobile"></el-table-column>
        <el-table-column align="center"
                         label="状态">
          <!-- 使用作用域插槽，scope.row表示这一行的数据 -->
          <template slot-scope="scope">
            <el-switch v-model="scope.row.mg_state"
                       @change="changeStatus(scope.row)"></el-switch>
          </template>
        </el-table-column>
        <el-table-column align="center"
                         label="注册时间">
          <template slot-scope="scope">
            {{ scope.row.create_time | formateTime }}
          </template>
        </el-table-column>
        <el-table-column label="操作"
                         width="120px"
                         align="center">
          <template slot-scope="scope">
            <!-- 【修改功能】 2.1 修改按钮 绑定事件 -->
            <el-button circle
                       type="success"
                       @click="editHandler(scope.row)"
                       size="small"
                       icon="el-icon-edit"></el-button>
            <!-- 【删除功能】 1. 删除按钮绑定事件 -->
            <el-button circle
                       type="danger"
                       @click="delHandler(scope.row)"
                       size="small"
                       icon="el-icon-delete"></el-button>
            <!-- 更换用户的角色信息 -->
            <el-button circle
                       type="warning"
                       @click="setUserRole(scope.row)"
                       size="small"
                       icon="el-icon-setting"></el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <!-- page-size属性 是每页数量 -->
      <!-- current-pages属性 是当前页码 -->
      <!-- total 属性表示总数 -->
      <br>
      <!-- <el-pagination
        @size-change="sizeChange"
        @current-change="currentChange"
        :current-page.sync="pagenum"
        :page-sizes="[1, 2, 3, 100]"
        :page-size="pagesize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total" background>
       >
      </el-pagination> -->
      <Pageination @sizechange="sizeChange"
                  @pagechange="currentChange"
                  :total="total"
                  :pagenum="pagenum"
                  :pagesize="pagesize"></Pageination>

    </div>

    <!-- 【增加功能】 2.1 准备弹框 -->
    <el-dialog title="增加用户"
               :visible.sync="isAddShow"
               @close="$refs.addForm.resetFields()"
               width="30%">
      <!-- 【增加功能】 3.2 定义表单 -->
      <el-form :model="addFormData"
               ref="addForm"
               :rules="addFormRules"
               label-width="80px"
               :inline="false"
               size="normal">
        <el-form-item label="用户名"
                      prop="username">
          <el-input v-model="addFormData.username"></el-input>
        </el-form-item>
        <el-form-item label="密码"
                      prop="password">
          <el-input v-model="addFormData.password"></el-input>
        </el-form-item>
        <el-form-item label="邮箱"
                      prop="email">
          <el-input v-model="addFormData.email"></el-input>
        </el-form-item>
        <el-form-item label="手机号"
                      prop="mobile">
          <el-input v-model="addFormData.mobile"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="$refs.addForm.resetFields()">重置</el-button>
        <el-button type="primary"
                   @click="addSumbit">提交</el-button>
      </span>
    </el-dialog>

    <!-- 【修改功能】 3.1 准备弹框 -->
    <el-dialog title="修改用户"
               :visible.sync="isEditShow"
               width="30%">
      <!-- 【修改功能】 3.2 定义表单 -->
      <el-form :model="editFormData"
               ref="editForm"
               :rules="editFormRules"
               label-width="80px"
               :inline="false"
               size="normal">
        <el-form-item label="邮箱"
                      prop="email">
          <el-input v-model="editFormData.email"></el-input>
        </el-form-item>
        <el-form-item label="手机号"
                      prop="mobile">
          <el-input v-model="editFormData.mobile"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="isEditShow = false">取消</el-button>
        <el-button type="primary"
                   @click="editSubmit">确定</el-button>
      </span>
    </el-dialog>

    <!-- 用户设置角色弹框 -->
    <el-dialog title="设置角色"
               :visible.sync="setRoleShow"
               @close="chooseRoleId=''"
               width="30%">
      <p><b>用户名:</b>{{userInfo.username}}</p>
      <p><b>角色名:</b>{{userInfo.role_name}}</p>
      <p><b>授权角色:
          <el-select v-model="chooseRoleId">
            <el-option v-for="item in roleList"
                       :key="item.id"
                       :label="item.roleName"
                       :value="item.id">
            </el-option>
          </el-select>
        </b>

      </p>
      <span slot="footer">
        <el-button @click="setRoleShow = false">Cancel</el-button>
        <el-button type="primary"
                   @click="setRoleSubmit">OK</el-button>
      </span>
    </el-dialog>

  </el-card>

</template>

<script>
const checkEmail = (rules, value, callback) => {
  const reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
  if (!value) return callback()
  if (reg.test(value)) {
    callback()
  } else {
    callback(new Error('邮箱格式不正确'))
  }
}
const checkMobile = (rules, value, callback) => {
  const reg = /^1[3|4|5|6|7|8|9]\d{9}$/
  if (!value) return callback()
  if (reg.test(value)) {
    callback()
  } else {
    callback(new Error('手机式不正确'))
  }
}
export default {
  name: 'Users',
  data () {
    return {
      // 搜索关键字
      keywords: '',
      // 【列表功能】1.定义变量
      list: [],
      // 当前页
      pagenum: 1,
      // 每页数量
      pagesize: 1,
      // 总数
      total: 0,
      // 【增加功能】2.2 弹框展示变量
      isAddShow: false,
      // 【增加功能】 3.1 定义表单的数据
      addFormData: {
        username: '',
        password: '',
        email: '',
        mobile: ''
      },
      // 添加表单验证规则
      addFormRules: {
        username: [{ required: true, message: '用户名必须！', trigger: 'blur' }],
        password: [{ required: true, message: '密码必须！', trigger: 'blur' }],
        // 自定义校验函数
        email: [{ validator: checkEmail, trigger: 'blur' }],
        mobile: [{ validator: checkMobile, trigger: 'blur' }]
      },
      // 【修改功能】1.1 弹框展示变量
      isEditShow: false,
      // 【修改功能】 1.2 定义修改表单的数据
      editFormData: {
        email: '',
        mobile: ''
      },
      // 修改表单的验证规则
      editFormRules: {
        // 自定义校验函数
        email: [{ validator: checkEmail, trigger: 'blur' }],
        mobile: [{ validator: checkMobile, trigger: 'blur' }]
      },
      // 角色设置弹框
      setRoleShow: false,
      // 用户信息
      userInfo: {
        username: '',
        role_name: ''
      },
      // 所有角色列表
      roleList: [],
      // 选择的角色ID
      chooseRoleId: ''
    }
  },
  created () {
    // 【列表功能】3. 调用获取列表方法
    this.getLoadList()
    this.getRoleList()
  },
  methods: {
    // 【列表功能】2. 获取用户列表数据
    async getLoadList () {
      // 2.1 发送请求
      const { data: res } = await this.$axios.get('/users', {
        params: {
          query: this.keywords,
          pagenum: this.pagenum,
          pagesize: this.pagesize
        }
      })
      // 2.2 错误处理
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      // 2.3 成功处理  （  处理数据(按需), 赋值 ）
      this.total = res.data.total
      this.list = res.data.users
    },
    // 获取所有角色列表信息
    async getRoleList () {
      // 发送请求
      const { data: res } = await this.$axios.get('/roles')
      // 错误处理
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      // 成功赋值
      this.roleList = res.data
    },
    // 每页数量更换事件
    sizeChange (val) {
      this.pagesize = val
      this.getLoadList()
    },
    // 页码更换事件
    currentChange (val) {
      this.pagenum = val
      this.getLoadList()
    },
    // 【增加功能】4. 用户添加提交事件
    addSumbit () {
      // 4.1 数据校验
      this.$refs.addForm.validate(async valid => {
        if (!valid) return this.$message.warning('验证不通过')
        // 4.2 提交数据
        const { data: res } = await this.$axios.post('/users', this.addFormData)
        // 错误处理
        if (res.meta.status !== 201) return this.$message.error(res.meta.msg)
        // 成功处理
        this.$message.success(res.meta.msg) // 成功提示
        this.isAddShow = false // 关闭弹框
        this.getLoadList() // 重新获取列表
        this.$refs.addForm.resetFields() // 重置表单（防止操作遗留）
      })
    },
    // 【修改功能】2.2 修改按钮的事件（回显表单数据、打开弹框）
    editHandler (val) {
      // 设置回显数据  (思路1：将这行的数据赋给回显表单、思路2：将这行的id提交给后台或者这行完整的数据赋给回显表单)
      this.editFormData.mobile = val.mobile
      this.editFormData.email = val.email
      this.editFormData.id = val.id
      // 打开修改弹框
      this.isEditShow = true
    },
    // 【修改功能】 4. 修改提交
    editSubmit () {
      // 验证表单数据
      this.$refs.editForm.validate(async valid => {
        if (!valid) return this.$message.warning('验证失败')
        // 提交数据
        const { data: res } = await this.$axios.put('/users/' + this.editFormData.id, this.editFormData)
        // 错误处理
        if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
        // 成功处理
        this.$message.success(res.meta.msg) // 提示
        this.isEditShow = false // 关闭弹框
        this.getLoadList() // 重新拉取列表
      })
    },
    // 修改用户状态
    async changeStatus (val) {
      const { data: res } = await this.$axios.put('/users/' + val.id + '/state/' + val.mg_state)
      if (res.meta.status !== 200) {
        val.mg_state = !val.mg_state // 失败就变回去
        return this.$message.error(res.meta.msg)
      }
      this.$message.success(res.meta.msg)
    },
    // 【删除功能】 2.删除事件
    async delHandler (row) {
      try {
        await this.$confirm('确定删除吗, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
        // 发送请求
        const { data: res } = await this.$axios.delete('/users/' + row.id)
        // 错误处理
        if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
        // 成功处理
        // 不是第一页，且这一页只有1个，删除成功后页码-1
        if (this.list.length === 1 && this.pagenum !== 1) this.pagenum--
        this.getLoadList()
      } catch (error) {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      }
    },
    // 设置用户角色
    setUserRole (row) {
      this.setRoleShow = true
      this.userInfo.username = row.username
      this.userInfo.role_name = row.role_name
      this.userInfo.id = row.id
    },
    // 用户授权角色提交事件
    async setRoleSubmit () {
      if (!this.chooseRoleId) return this.$message.warning('请选择角色')
      const { data: res } = await this.$axios.put('/users/' + this.userInfo.id + '/role', {
        rid: this.chooseRoleId
      })
      if (res.meta.status !== 200) return this.$message.warning(res.meta.msg)
      this.$message.success(res.meta.msg)
      this.setRoleShow = false
      this.getLoadList()
    }
  }
}
// 列表思路：
// 1. data里面定义列表变量
// 2. methods里面定义数据请求方法(发送请求、失败处理、成功处理(处理数据、赋值数据)  )
// 3. 生命周期created里面触发数据请求方法
// 4. 页面模板中渲染列表的表格数据

// 分页思路：
// 1.定义三个变量（每页数量，每页个数，总数）  2个事件（页码更换事件、每页数量更换事件）
// 2.将每页数量和每页个数绑定给查询接口
// 3.页面更换事件和每页数量更换事件里面将最新页码和每页数量赋给data里面对应变量，再去请求数据列表

// 条件查询思路
// 1.定义相关搜索相关表单变量，关联搜索表单组件
// 2.将搜索变量给查询接口

// 增加功能思路：
// 1. 页面里面增加增加绑定事件(设置弹框显示的变量为true)
// 2. 准备弹框（弹框显示变量、准备弹框组件、按钮绑定改为true）
// 3、准备表单（data里表单变量定义、模板书写表单组件）
// 4、methods定义表单数据提交事件（验证、发送请求、错误处理、成功处理=>重置表单、关闭弹框、重新拉取列表）

// 修改功能思路：
// 1. 准备弹框显示变量、修改表单变量
// 2. 表格里面的修改按钮绑定事件(传入这一行的数据)，绑定的事件里面完成2件事
// 数据回显(使用传入的数据赋给表单回显；传入这行的id去后端请求，返回数据赋给表单回显)
// 弹框显示变量为true
// 3. 准备弹框、准备表单、绑定数据
// 4. 修改提交（验证表单数据、提交数据、错误处理、成功处理=>关闭弹框、重新拉取列表）

// 删除功能思路：
// 1. 表格里面的删除按钮绑定删除事件
// 2. 定义删除事件， 确认框弹出 是否确认删除，确认删除就 发送请求(错误处理、成功处理=>判断页码是否退1、重新拉取列表)
</script>

<style lang="less">

</style>
